﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using NAudio;
using NAudio.Wave;
using System.Threading;

namespace NotifierService.Server
{
    internal class AudioReceiver
    {
        #region Fields

        private IWavePlayer _waveOut;
        private BufferedWaveProvider _waveProvider;
        private UdpClient _udpListener;
        private IAudioCodec _audioCodec;
        private volatile bool _isRunning = false;
        private IPEndPoint _endPoint;

        #endregion

        public AudioReceiver() { }


        public void Start()
        { 
            if (_isRunning)
                throw new InvalidOperationException("This receiver is already running.");

            IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1234);
            _audioCodec = new WideBandSpeexCodec();
            PrivateStart(endPoint);
        }


        #region Private Methods

        private void PrivateStart(IPEndPoint endPoint)
        { 
            _isRunning = true;

            _udpListener = new UdpClient();
            _udpListener.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
            _udpListener.Client.Bind(endPoint);
            _endPoint = endPoint;

            _waveOut = new WaveOut();
            _waveProvider = new BufferedWaveProvider(_audioCodec.RecordFormat);
            _waveOut.Init(_waveProvider);
            _waveOut.Play();

            ThreadPool.QueueUserWorkItem(UdpListenerProc, null);
        }


        private void UdpListenerProc(object state)
        {
            try
            {
                while (_isRunning)
                {
                    byte[] b = _udpListener.Receive(ref _endPoint);
                    byte[] decoded = _audioCodec.Decode(b, 0, b.Length);
                    _waveProvider.AddSamples(decoded, 0, decoded.Length);
                }
            } catch (SocketException)
            {

            }
            catch (Exception)
            {

            }
        }


        #endregion
    }
}
